package com.zhangmeng.tools.controller;

import cn.hutool.core.io.BufferUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.socket.aio.AioClient;
import cn.hutool.socket.aio.AioSession;
import cn.hutool.socket.aio.SimpleIoAction;
import cn.hutool.socket.nio.NioClient;
import com.zhangmeng.tools.utils.AlertUtils;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.Date;

/**
 * @author : 芊芊墨客
 * @version : 1.0
 * @date : 2023-05-06 10:38
 */
@Slf4j
public class NioClientSocketController {

    @FXML
    public TextField ip_address;

    @FXML
    public TextArea content;

    @FXML
    public Button connection;

    @FXML
    public TextField input;

    @FXML
    public Button send;

    @FXML
    public TextField port;

    @FXML
    public Button disconn;

    private NioClient client;

    private void appendMsg(String msg) {
        content.appendText(System.lineSeparator());
        content.appendText(msg);
    }

    @FXML
    public void initialize() {
        ip_address.setText("localhost");
        port.setText("8083");
        connection.setOnAction(event -> {
            content.setText(null);
            if (ip_address.getText().length() == 0 ){
                AlertUtils.alert_warning("ip不能为空");
                return;
            }
            if (port.getText().length() == 0 ){
                AlertUtils.alert_warning("端口不能为空");
                return;
            }

            client = new NioClient(ip_address.getText(), Integer.parseInt(port.getText()));
            client.setChannelHandler((sc)->{
                ByteBuffer readBuffer = ByteBuffer.allocate(1024);
                //从channel读数据到缓冲区
                int readBytes = sc.read(readBuffer);
                if (readBytes > 0) {
                    //Flips this buffer.  The limit is set to the current position and then
                    // the position is set to zero，就是表示要从起始位置开始读取数据
                    readBuffer.flip();
                    //returns the number of elements between the current position and the  limit.
                    // 要读取的字节长度
                    byte[] bytes = new byte[readBuffer.remaining()];
                    //将缓冲区的数据读到bytes数组
                    readBuffer.get(bytes);
                    String body = StrUtil.utf8Str(bytes);
                    appendMsg("========>客户端接收"  + new Date()  + "=======>:" +  body);
                } else if (readBytes < 0) {
                    sc.close();
                }
            });
            client.listen();
        });

        send.setOnAction(event -> {
            send();
        });

        disconn.setOnAction(event -> {
            client.close();
        });
    }

    private void send() {
        if (input.getText().length() == 0) {
            AlertUtils.alert_warning("发送的内容不能为空");
            return;
        }
        String msg = input.getText();
        try {
            doWrite(client.getChannel(),msg);
        } catch (IOException e) {
            e.printStackTrace();
        }
        appendMsg("========>客户端发送"  + new Date()  + "=======>:" + msg );
    }

    public static void doWrite(SocketChannel channel, String msg) throws IOException {
        //将缓冲数据写入渠道，返回给客户端
        channel.write(BufferUtil.createUtf8(msg));
    }
}
